package it.univaq.mwt.arssa.business.impl;

import it.univaq.mwt.arssa.business.BusinessException;
import it.univaq.mwt.arssa.business.DipendentiService;
import it.univaq.mwt.arssa.business.model.Dipendente;
import it.univaq.mwt.arssa.business.model.ImgDipendenti;
import it.univaq.mwt.arssa.business.model.Ruolo;
import it.univaq.mwt.arssa.business.model.Sede;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

public class JDBCDipendentiService implements DipendentiService {
	
	private DataSource dataSource;
	
	public JDBCDipendentiService(DataSource dataSource){
		this.dataSource = dataSource;
	}

	@Override
	public List<Dipendente> cercaDipendenti() {
		Connection con = null;
		Statement st = null;
		ResultSet rs = null;
		List<Dipendente> result = new ArrayList<Dipendente>();
				
		
		try {
			con = dataSource.getConnection();
			st = con.createStatement();
			rs = st.executeQuery("SELECT * FROM DIPENDENTI ORDER BY ID DESC");
			while (rs.next()) {
				int id = rs.getInt("ID");
				String matricola = rs.getString("MATRICOLA");
				String username = rs.getString("USERNAME");
				String password = rs.getString("PASSWORD");
				String nome = rs.getString("NOME");
				String cognome = rs.getString("COGNOME");
				String codiceFiscale = rs.getString("CODICEFISCALE");
				String email = rs.getString("EMAIL");
				String cellulare = rs.getString("CELLULARE");
				int ruolo = rs.getInt("IDRUOLO");
				int sede = rs.getInt("IDSEDE");
				int ferieRimanenti = rs.getInt("FERIERIMANENTI");
				String straordinari = rs.getString("STRAORDINARI");
				String citta = rs.getString("CITTA");
				String via = rs.getString("VIA");
				String numeroCivico = rs.getString("NUMEROCIVICO");	
				JDBCRuoliService serviceRuoli = new JDBCRuoliService(dataSource);
				JDBCSediService serviceSedi = new JDBCSediService(dataSource);
				Ruolo r1 = serviceRuoli.cercaRuolo(ruolo);
				Sede s1 = serviceSedi.cercaSede(sede);
							
				result.add(new Dipendente(id, matricola, username, password, nome, cognome, codiceFiscale, email, cellulare, citta, via, numeroCivico, r1, s1, ferieRimanenti, straordinari));
			}

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}
		return result;
	}

	@Override
	public Dipendente cercaDipendente(int id) {
		
		Connection con = null;
		PreparedStatement st = null;
		ResultSet rs = null;
		Dipendente result = null;
		try {
			
			con = dataSource.getConnection();
			st = con.prepareStatement("SELECT * FROM Dipendenti WHERE id=?");
			st.setInt(1, id);
			rs = st.executeQuery();
			
			if (rs.next()) {
				String matricola = rs.getString("MATRICOLA");
				String username = rs.getString("USERNAME");
				String password = rs.getString("PASSWORD");
				String nome = rs.getString("NOME");
				String cognome = rs.getString("COGNOME");
				String codiceFiscale = rs.getString("CODICEFISCALE");
				String email = rs.getString("EMAIL");
				String cellulare = rs.getString("CELLULARE");
				int ruolo = rs.getInt("IDRUOLO");
				int sede = rs.getInt("IDSEDE");
				int ferieRimanenti = rs.getInt("FERIERIMANENTI");
				String straordinari = rs.getString("STRAORDINARI");
				String citta = rs.getString("CITTA");
				String via = rs.getString("VIA");
				String numeroCivico = rs.getString("NUMEROCIVICO");
				
				JDBCRuoliService serviceRuoli = new JDBCRuoliService(dataSource);
				JDBCSediService serviceSedi = new JDBCSediService(dataSource);
				Ruolo r1 = serviceRuoli.cercaRuolo(ruolo);
				Sede s1 = serviceSedi.cercaSede(sede);
							
				result = (new Dipendente(id, matricola, username, password, nome, cognome, codiceFiscale, email, cellulare, citta, via, numeroCivico, r1, s1, ferieRimanenti, straordinari));
			}

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}

		return result;
	
	}
		
	@Override
	public Dipendente cercaDipendente(String matricola) {
		Connection con = null;
		PreparedStatement st = null;
		ResultSet rs = null;
		Dipendente result = null;
		try {
			
			con = dataSource.getConnection();
			st = con.prepareStatement("SELECT * FROM DIPENDENTI WHERE MATRICOLA=?");
			st.setString(1, matricola);
			rs = st.executeQuery();
			
			if (rs.next()) {
				int id = rs.getInt("ID");
				String username = rs.getString("USERNAME");
				String password = rs.getString("PASSWORD");
				String nome = rs.getString("NOME");
				String cognome = rs.getString("COGNOME");
				String codiceFiscale = rs.getString("CODICEFISCALE");
				String email = rs.getString("EMAIL");
				String cellulare = rs.getString("CELLULARE");
				int ruolo = rs.getInt("IDRUOLO");
				int sede = rs.getInt("IDSEDE");
				int ferieRimanenti = rs.getInt("FERIERIMANENTI");
				String straordinari = rs.getString("STRAORDINARI");
				String citta = rs.getString("CITTA");
				String via = rs.getString("VIA");
				String numeroCivico = rs.getString("NUMEROCIVICO");
				
				JDBCRuoliService serviceRuoli = new JDBCRuoliService(dataSource);
				JDBCSediService serviceSedi = new JDBCSediService(dataSource);
				Ruolo r1 = serviceRuoli.cercaRuolo(ruolo);
				Sede s1 = serviceSedi.cercaSede(sede);
							
				result = (new Dipendente(id, matricola, username, password, nome, cognome, codiceFiscale, email, cellulare, citta, via, numeroCivico, r1, s1, ferieRimanenti, straordinari));
			}

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}

		return result;
	}

	@Override
	public ImgDipendenti cercaImmagine(int idDipendente) {
		
		Connection con = null;
		PreparedStatement st = null;
		ResultSet rs = null;
		ImgDipendenti result = null;
		try {
			
			con = dataSource.getConnection();
			st = con.prepareStatement("SELECT * FROM IMGDIPENDENTI WHERE IDDIPENDENTE=?");
			st.setInt(1, idDipendente);
			rs = st.executeQuery();
			
			if (rs.next()) {
				int id = rs.getInt("ID");
				String nome = rs.getString("NOME");
				String contentType = rs.getString("CONTENTTYPE");
				int dimensione = rs.getInt("DIMENSIONE");
				byte[] bytes = rs.getBytes("BYTES");
				
				result = (new ImgDipendenti(id, idDipendente, bytes, dimensione, nome, contentType));
			}

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}

		return result;
	}

	@Override
	public void modificaDipendente(Dipendente dipendente) {
		
		Connection con = null;
		PreparedStatement st = null;
		
		try {					
			con = dataSource.getConnection();	
			
			st = con.prepareStatement("UPDATE DIPENDENTI SET MATRICOLA = ?, NOME = ?, COGNOME = ?, CODICEFISCALE = ?, EMAIL = ?, CELLULARE = ?, IDRUOLO = ?, IDSEDE = ?, FERIERIMANENTI = ?, STRAORDINARI = ?, CITTA = ?, VIA = ?, NUMEROCIVICO = ?, USERNAME = ?, PASSWORD = ?  WHERE (ID = ?)");		
			st.setString(1, dipendente.getMatricola());
			st.setString(2, dipendente.getNome());
			st.setString(3, dipendente.getCognome());
			st.setString(4, dipendente.getCodiceFiscale());
			st.setString(5, dipendente.getEmail());
			st.setString(6, dipendente.getCellulare());
			st.setInt(7, dipendente.getRuolo().getId());
			st.setInt(8, dipendente.getSede().getId());
			st.setInt(9, dipendente.getFerie());
			st.setString(10, dipendente.getStraordinari());
			st.setString(11, dipendente.getCitta());
			st.setString(12, dipendente.getVia());
			st.setString(13, dipendente.getNumeroCivico());
			st.setString(14, dipendente.getUsername());
			st.setString(15, dipendente.getPassword());
			st.setInt(16, dipendente.getId());
						
			st.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}
		
	}

	@Override
	public void modificaFotoDipendente(ImgDipendenti imgdipendente) {
		
		Connection con = null;
		PreparedStatement st = null;
		try {
			con = dataSource.getConnection();
			st = con.prepareStatement("UPDATE IMGDIPENDENTI SET bytes=?, dimensione=?, contenttype=?, nome=? WHERE iddipendente=?");
			st.setBytes(1,imgdipendente.getBytes());
			st.setInt(2, imgdipendente.getDimensione());
			st.setString(3, imgdipendente.getContentType());
			st.setString(4, imgdipendente.getNome());	
			st.setInt(5, imgdipendente.getIdDipendente());
			st.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}
		
	}

	@Override
	public void inserisciDipendente(Dipendente dipendente) {
		
		Connection con = null;
		PreparedStatement st = null;
		try {
			con = dataSource.getConnection();
			st = con.prepareStatement("INSERT INTO DIPENDENTI (id, matricola, username, password, nome, cognome, codiceFiscale, email, cellulare, idRuolo, idSede, ferieRimanenti, straordinari, citta, via, numeroCivico) VALUES (NULL,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
			st.setString(1,dipendente.getMatricola());
			st.setString(2, dipendente.getUsername());
			st.setString(3, dipendente.getPassword());
			st.setString(4, dipendente.getNome());
			st.setString(5, dipendente.getCognome());
			st.setString(6, dipendente.getCodiceFiscale());
			st.setString(7, dipendente.getEmail());			
			st.setString(8, dipendente.getCellulare());
			st.setInt(9, dipendente.getRuolo().getId());
			st.setInt(10, dipendente.getSede().getId());
			st.setInt(11, dipendente.getFerie());
			st.setString(12, dipendente.getStraordinari());
			st.setString(13, dipendente.getCitta());
			st.setString(14, dipendente.getVia());
			st.setString(15, dipendente.getNumeroCivico());						
			st.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}
		
	}
	
	@Override
	public void inserisciFotoDipendente(ImgDipendenti imgdipendente) {

		Connection con = null;
		PreparedStatement st = null;
		try {
			con = dataSource.getConnection();
			st = con.prepareStatement("INSERT INTO IMGDIPENDENTI (id, bytes, dimensione, contenttype, nome,iddipendente) VALUES (NULL,?,?,?,?,?)");
			st.setBytes(1,imgdipendente.getBytes());
			st.setInt(2, imgdipendente.getDimensione());
			st.setString(3, imgdipendente.getContentType());
			st.setString(4, imgdipendente.getNome());	
			st.setInt(5, imgdipendente.getIdDipendente());
			st.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}
		
	}

	@Override
	public void eliminaFotoDipendente(int idDipendente) {
			
		Connection con = null;
		PreparedStatement st = null;
		try {
			con = dataSource.getConnection();
			st = con.prepareStatement("DELETE FROM IMGDIPENDENTI WHERE IDDIPENDENTE=?");
			st.setInt(1, idDipendente);
			st.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}
		
	}
	
	@Override
	public void eliminaDipendente(int idDipendente) {
			
		Connection con = null;
		PreparedStatement st = null;
		try {
			con = dataSource.getConnection();
			st = con.prepareStatement("DELETE FROM DIPENDENTI WHERE ID=?");
			st.setInt(1, idDipendente);
			st.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}
		
	}
	
	
	
	@Override
	public void aggiornaFerie() {
		
		Connection con = null;
		PreparedStatement st = null;
		PreparedStatement st1 = null;
		ResultSet rs = null;
		
		try {
			con = dataSource.getConnection();
			st = con.prepareStatement("SELECT * FROM DIPENDENTI ");
			rs = st.executeQuery();
			
			while(rs.next()){
				int id = rs.getInt("ID");
				int ferieRimanenti = rs.getInt("FERIERIMANENTI");
				ferieRimanenti+= 30; //incremento di 30 giorni le ferie

				st1 = con.prepareStatement("UPDATE DIPENDENTI SET  FERIERIMANENTI = ?  WHERE (ID = ?)");		
				st1.setInt(1, ferieRimanenti);
				st1.setInt(2, id);			
				st1.executeUpdate();

			}

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}

	}

	@Override
	public int calcolaFerieRimanenti(int idDipendente) {
		
		Connection con = null;
		PreparedStatement st = null;
		ResultSet rs = null;
		int result = 0;
		
		try {
			con = dataSource.getConnection();
			st = con.prepareStatement("SELECT * FROM Dipendenti WHERE id=?");
			st.setInt(1, idDipendente);
			rs = st.executeQuery();
			
			if(rs.next()){
				result = rs.getInt("FERIERIMANENTI");
			}

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}
		
		return result;
	}
	
	@Override
	public boolean verificaUsername(String username) {
		Connection con = null;
		PreparedStatement st = null;
		ResultSet rs = null;
		
		try {
			con = dataSource.getConnection();
			st = con.prepareStatement("SELECT * FROM DIPENDENTI WHERE USERNAME=?");
			st.setString(1, username);
			rs = st.executeQuery();
			
			if(rs.next()){
				return true;
			}

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}
		return false;
	}

	@Override
	public boolean verificaCodiceFiscale(String codiceFiscale) {
		Connection con = null;
		PreparedStatement st = null;
		ResultSet rs = null;
		
		try {
			con = dataSource.getConnection();
			st = con.prepareStatement("SELECT * FROM DIPENDENTI WHERE CODICEFISCALE=?");
			st.setString(1, codiceFiscale);
			rs = st.executeQuery();
			
			if(rs.next()){
				return true;
			}

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}
		return false;
	}

	@Override
	public boolean verificaNomeCognome(String nome,String cognome) {
		Connection con = null;
		PreparedStatement st = null;
		ResultSet rs = null;
		
		try {
			con = dataSource.getConnection();
			st = con.prepareStatement("SELECT * FROM DIPENDENTI WHERE NOME=? AND COGNOME=?");
			st.setString(1, nome);
			st.setString(2, cognome);
			rs = st.executeQuery();
			
			if(rs.next()){
				return true;
			}

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}
		return false;
	}

	@Override
	public boolean verificaMatricola(String matricola) {
		Connection con = null;
		PreparedStatement st = null;
		ResultSet rs = null;
		
		try {
			con = dataSource.getConnection();
			st = con.prepareStatement("SELECT * FROM DIPENDENTI WHERE MATRICOLA=?");
			st.setString(1, matricola);
			rs = st.executeQuery();
			
			if(rs.next()){
				return true;
			}

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}
		return false;
	}
	
	@Override
	public boolean verificaEmail(String email) {
		Connection con = null;
		PreparedStatement st = null;
		ResultSet rs = null;
		
		try {
			con = dataSource.getConnection();
			st = con.prepareStatement("SELECT * FROM DIPENDENTI WHERE EMAIL=?");
			st.setString(1, email);
			rs = st.executeQuery();
			
			if(rs.next()){
				return true;
			}

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}
		return false;
	}
	
	@Override
	public boolean verificaCellulare(String cellulare) {
		Connection con = null;
		PreparedStatement st = null;
		ResultSet rs = null;
		
		try {
			con = dataSource.getConnection();
			st = con.prepareStatement("SELECT * FROM DIPENDENTI WHERE CELLULARE=?");
			st.setString(1, cellulare);
			rs = st.executeQuery();
			
			if(rs.next()){
				return true;
			}

		} catch (SQLException e) {
			e.printStackTrace();
			throw new BusinessException(e);
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}

		}
		return false;
	}
	
	
}
